package gamesession

import (
	"errors"              // 用于定义会话管理相关的错误
	"gameServer/eventbus" // 事件总线包，用于会话生命周期事件的发布（如会话创建/移除）
	"gameServer/log"      // 日志包，记录会话管理的关键操作（如创建、过期、移除）
	"sync"                // 提供读写锁，确保会话管理在并发环境下的安全操作
	"time"                // 用于会话ID生成、超时判断和定时清理
)

/*
本文件实现了游戏会话管理器（SessionManager），负责会话的统一创建、查询、移除和自动清理，
结合事件总线实现会话生命周期的事件通知，同时通过定时任务清理过期会话，避免资源泄漏。
*/

// SessionManager 游戏会话管理器，负责集中管理所有游戏会话的生命周期，
// 提供并发安全的会话操作接口，并支持自动清理过期会话
type SessionManager struct {
	sessions map[string]GameSession // 存储所有会话的映射表：key为会话ID（sessionID），value为会话实例
	mu       sync.RWMutex           // 读写锁：读操作（如查询会话）用RLock，写操作（如创建/移除会话）用Lock
	eventBus eventbus.EventBus      // 事件总线实例，用于发布会话生命周期事件（如会话创建、移除）
	config   ManagerConfig          // 会话管理器配置，控制最大会话数、清理间隔等规则
	monitor  *Monitor               // 会话监控器实例
	// storage     SessionStorage         // 会话存储接口（已禁用）
}

// ManagerConfig 会话管理器的配置结构体，定义管理器的核心运行规则
type ManagerConfig struct {
	MaxSessions     int           `json:"max_sessions"`     // 管理器允许的最大会话数量，超过则无法创建新会话
	CleanupInterval time.Duration `json:"cleanup_interval"` // 自动清理过期会话的时间间隔（如5*time.Minute表示每5分钟清理一次）
	SessionTimeout  time.Duration `json:"session_timeout"`  // 会话的空闲超时时间（如30*time.Second表示空闲30秒的会话视为过期）
}

// NewSessionManager 创建会话管理器实例，初始化内部存储结构，并启动自动清理的定时任务
// 参数：
//
//	eventBus: 事件总线实例，用于发布会话相关事件（如EventSessionCreated、EventSessionRemoved）
//	config: 会话管理器配置，定义最大会话数、清理间隔等规则
//
// 返回值：
//
//	*SessionManager: 初始化后的会话管理器实例
func NewSessionManager(eventBus eventbus.EventBus, config ManagerConfig) *SessionManager {
	manager := &SessionManager{
		sessions: make(map[string]GameSession), // 初始化会话映射表为空map
		eventBus: eventBus,                     // 赋值事件总线，用于后续发布事件
		config:   config,                       // 赋值管理器配置

	}
	// 启动自动清理的goroutine（独立线程），定时清理过期会话
	// 创建并启动监控器
	manager.monitor = NewMonitor(manager)
	manager.monitor.Start(30 * time.Second) // 每30秒收集一次统计
	go manager.cleanupRoutine()
	return manager
}

// CreateSession 创建一个新的游戏会话，并添加到管理器中
// 参数：
//
//	config: 会话配置（如最大/最小玩家数、是否自动启动），用于初始化会话实例
//
// 返回值：
//
//	GameSession: 创建成功的会话实例
//	error: 成功返回nil；失败返回错误（如超过最大会话数、会话ID生成失败）
func (m *SessionManager) CreateSession(config SessionConfig) (GameSession, error) {
	// 生成唯一的会话ID（格式：session_时间戳_随机字符串）
	sessionID := generateSessionID()

	m.mu.Lock()         // 加写锁，确保创建会话时的并发安全（避免同时创建导致map竞争）
	defer m.mu.Unlock() // 函数退出时自动释放锁

	// 检查当前会话数是否已达最大限制（MaxSessions）
	if len(m.sessions) >= m.config.MaxSessions {
		return nil, errors.New("max sessions reached")
	}

	// 创建基础会话实例（基于传入的会话配置）
	session := NewBaseSession(sessionID, config)
	// 将新会话添加到管理器的会话映射表中
	m.sessions[sessionID] = session
	// 发布“会话创建”事件到事件总线，通知其他模块（如日志模块、监控模块）
	// 注：原代码中NewBaseEvent参数可能存在笔误（多传了空字符串），此处按原逻辑注释
	m.eventBus.Publish(eventbus.NewBaseEvent(
		eventbus.EventSessionCreated, // 事件名称：会话创建
		// sessionID,                    // 事件数据1：会话ID
		// "",                           // 冗余参数（疑似笔误，无实际意义）
		map[string]interface{}{ // 事件数据2：会话配置（以map形式携带）
			"config": config,
		},
	))

	log.Infof("session created: %s", sessionID) // 记录会话创建日志
	return session, nil
}

func (m *SessionManager) CreateSessionById(id string, config SessionConfig) (GameSession, error) {
	// 生成唯一的会话ID（格式：session_时间戳_随机字符串）
	sessionID := id

	m.mu.Lock()         // 加写锁，确保创建会话时的并发安全（避免同时创建导致map竞争）
	defer m.mu.Unlock() // 函数退出时自动释放锁

	// 检查当前会话数是否已达最大限制（MaxSessions）
	if len(m.sessions) >= m.config.MaxSessions {
		return nil, errors.New("max sessions reached")
	}

	// 创建基础会话实例（基于传入的会话配置）
	session := NewBaseSession(sessionID, config)
	// 将新会话添加到管理器的会话映射表中
	m.sessions[sessionID] = session

	// 发布“会话创建”事件到事件总线，通知其他模块（如日志模块、监控模块）
	// 注：原代码中NewBaseEvent参数可能存在笔误（多传了空字符串），此处按原逻辑注释
	m.eventBus.Publish(eventbus.NewBaseEvent(
		eventbus.EventSessionCreated, // 事件名称：会话创建
		// sessionID,                    // 事件数据1：会话ID
		// "",                           // 冗余参数（疑似笔误，无实际意义）
		map[string]interface{}{ // 事件数据2：会话配置（以map形式携带）
			"config": config,
		},
	))
	log.Infof("session created: %s", sessionID) // 记录会话创建日志
	return session, nil
}

// GetSession 根据会话ID从管理器中获取会话实例
// 参数：
//
//	sessionID: 要查询的会话唯一标识
//
// 返回值：
//
//	GameSession: 找到的会话实例（若存在）
//	error: 成功返回nil；会话不存在时返回错误
func (m *SessionManager) GetSession(sessionID string) (GameSession, error) {
	m.mu.RLock()         // 加读锁，允许并发查询（不阻塞其他读操作）
	defer m.mu.RUnlock() // 函数退出时自动释放锁

	// 从会话映射表中查找指定ID的会话
	session, exists := m.sessions[sessionID]
	if !exists {
		return nil, errors.New("session not found") // 会话不存在，返回错误
	}
	return session, nil
}

// RemoveSession 根据会话ID从管理器中移除会话，并发布“会话移除”事件
// 参数：
//
//	sessionID: 要移除的会话唯一标识
//
// 返回值：
//
//	error: 成功返回nil；会话不存在时返回错误
func (m *SessionManager) RemoveSession(sessionID string) error {
	m.mu.Lock()         // 加写锁，确保移除会话时的并发安全
	defer m.mu.Unlock() // 函数退出时自动释放锁

	// 检查会话是否存在
	if _, exists := m.sessions[sessionID]; !exists {
		return errors.New("session not found") // 会话不存在，返回错误
	}

	// 从会话映射表中删除指定会话
	delete(m.sessions, sessionID)

	// 发布“会话移除”事件到事件总线，通知其他模块
	m.eventBus.Publish(eventbus.NewSessionEvent(
		eventbus.EventSessionRemoved, // 事件名称：会话移除
		sessionID,                    // 事件数据1：会话ID
		"",                           // 冗余参数（疑似笔误）
		nil,                          // 额外数据（此处为nil）
	))

	log.Infof("session removed: %s", sessionID) // 记录会话移除日志
	return nil
}

// FindAvailableSession 查找一个“可加入”的会话（即满足CanJoin()条件的会话）
// 返回值：
//
//	GameSession: 找到的可加入会话实例（若存在）
//	error: 成功返回nil；无可用会话时返回错误
func (m *SessionManager) FindAvailableSession() (GameSession, error) {
	m.mu.RLock()         // 加读锁，允许并发查询
	defer m.mu.RUnlock() // 函数退出时自动释放锁

	// 遍历所有会话，找到第一个满足CanJoin()的会话（CanJoin()判断：状态为Idle/Matching且未达最大玩家数）
	for _, session := range m.sessions {
		if session.CanJoin() {
			return session, nil
		}
	}

	return nil, errors.New("no available session") // 无可用会话，返回错误
}

// GetAllSessions 获取管理器中所有的会话实例
// 返回值：
//
//	[]GameSession: 包含所有会话实例的切片（为避免外部修改内部map，返回新创建的切片）
//	error: 始终返回nil（预留用于后续扩展错误场景）
func (m *SessionManager) GetAllSessions() ([]GameSession, error) {
	m.mu.RLock()         // 加读锁，允许并发查询
	defer m.mu.RUnlock() // 函数退出时自动释放锁

	// 初始化切片（容量为当前会话数，避免扩容）
	sessions := make([]GameSession, 0, len(m.sessions))
	// 遍历会话映射表，将所有会话实例添加到切片中
	for _, session := range m.sessions {
		sessions = append(sessions, session)
	}
	return sessions, nil
}

// cleanupRoutine 自动清理的定时任务（独立goroutine运行），每隔CleanupInterval触发一次清理
func (m *SessionManager) cleanupRoutine() {
	// 创建一个定时器，每隔m.config.CleanupInterval（如5分钟）触发一次
	ticker := time.NewTicker(m.config.CleanupInterval)
	defer ticker.Stop() // 函数退出时停止定时器，避免资源泄漏
	// saveTicker := time.NewTicker(30 * time.Second) // 每30秒保存一次（已禁用）
	// defer saveTicker.Stop()
	// for range ticker.C：监听定时器的通道，每次定时器触发时会向通道发送当前时间

	for range ticker.C {
		select {
		case <-ticker.C:
			m.cleanupExpiredSessions()
			// case <-saveTicker.C:
			// 	m.saveAllSessions()
		}
	}
}

// saveAllSessions 保存所有活跃会话到存储（已禁用）
/*
func (m *SessionManager) saveAllSessions() {
	m.mu.RLock()
	defer m.mu.RUnlock()

	for sessionID, session := range m.sessions {
		if err := m.saveSession(session); err != nil {
			log.Infof("Failed to save session %s during periodic save: %v", sessionID, err)
		}
	}
}*/

// cleanupExpiredSessions 清理过期的会话（空闲状态且超过超时时间的空会话）
func (m *SessionManager) cleanupExpiredSessions() {
	m.mu.RLock()         // 加读锁，遍历会话时允许并发读（但后续删除需注意锁转换，原代码此处存在小问题，注释按原逻辑）
	defer m.mu.RUnlock() // 函数退出时自动释放锁

	now := time.Now() // 获取当前时间，用于计算会话存活时长
	expiredSessions := make([]string, 0)
	// 检查所有会话是否过期
	for sessionID, session := range m.sessions {
		if session.IsExpired(m.config.SessionTimeout) {
			expiredSessions = append(expiredSessions, sessionID)
		}
	}
	// 清理过期会话
	for _, sessionID := range expiredSessions {
		session := m.sessions[sessionID]

		// 从存储中删除（已禁用）
		/*
		   if err := m.storage.DeleteSession(sessionID); err != nil {
		   	log.Infof("Failed to delete expired session %s from storage: %v", sessionID, err)
		   }

		   // 从列表中移除（已禁用）
		   if err := m.removeSessionFromList(sessionID); err != nil {
		   	log.Infof("Failed to remove expired session %s from list: %v", sessionID, err)
		   }
		*/

		delete(m.sessions, sessionID)
		log.Infof("Session expired and cleaned up: %s", sessionID)

		// 发布会话过期事件
		m.eventBus.Publish(eventbus.NewSessionEvent(
			eventbus.EventSessionExpired,
			sessionID,
			"",
			map[string]interface{}{
				"reason": "session timeout",
			},
		))
		if session.State() == StateIdle && now.Sub(session.CreateAt()) > m.config.SessionTimeout {
			if session.IsEmpty() {
				delete(m.sessions, sessionID)               // 从映射表中删除过期会话
				log.Infof("session expired: %s", sessionID) // 记录会话过期日志
			}
		}
	}
	// // 遍历所有会话，判断是否需要清理
	// for sessionID, session := range m.sessions {
	// 	// 过期条件：1. 会话状态为Idle（空闲）；2. 会话创建时间距现在超过SessionTimeout；3. 会话无玩家（IsEmpty()）
	// 	if session.State() == StateIdle && now.Sub(session.CreateAt()) > m.config.SessionTimeout {
	// 		if session.IsEmpty() {
	// 			delete(m.sessions, sessionID)               // 从映射表中删除过期会话
	// 			log.Infof("session expired: %s", sessionID) // 记录会话过期日志
	// 		}
	// 	}
	// }
}

// generateSessionID 生成唯一的会话ID，格式为“session_时间戳_随机字符串”
// 返回值：
//
//	string: 唯一的会话ID（基于当前时间和简化的随机字符串，确保唯一性）
func generateSessionID() string {
	// 时间戳格式：20060102150405（年月日时分秒），确保同一秒内的ID有区分度
	// randomString(0)：当前生成空字符串（简化实现，实际应传入正数长度生成随机串）
	return "session_" + time.Now().Format("20060102150405") + "_" + randomString(0)
}

// AddPlayerToSession 添加玩家到会话
func (m *SessionManager) AddPlayerToSession(sessionID, playerID string) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	session, exists := m.sessions[sessionID]
	if !exists {
		return errors.New("session not found")
	}

	if err := session.AddPlayer(playerID); err != nil {
		return err
	}
	// 保存会话状态到存储（已禁用）
	/*
	   if err := m.saveSession(session); err != nil {
	   	log.Infof("Failed to save session after adding player: %v", err)
	   }*/
	// 发布玩家加入事件
	m.eventBus.Publish(eventbus.NewSessionEvent(
		eventbus.EventPlayerJoined,
		sessionID,
		playerID,
		map[string]interface{}{
			"player_count": session.PlayerCount(),
		},
	))

	log.Infof("Player %s joined session %s", playerID, sessionID)
	return nil
}

// RemovePlayerFromSession 从会话移除玩家
func (m *SessionManager) RemovePlayerFromSession(sessionID, playerID string) error {
	m.mu.Lock()
	defer m.mu.Unlock()

	session, exists := m.sessions[sessionID]
	if !exists {
		return errors.New("session not found")
	}

	if err := session.RemovePlayer(playerID); err != nil {
		return err
	}
	// 保存会话状态到存储（已禁用）
	/*
	   if err := m.saveSession(session); err != nil {
	   	log.Infof("Failed to save session after removing player: %v", err)
	   }*/
	// 如果会话为空，考虑删除（或等待清理）
	if session.IsEmpty() {
		// 可选：立即删除空会话
		// delete(m.sessions, sessionID)
		// m.storage.DeleteSession(sessionID)
	}
	// 发布玩家离开事件
	m.eventBus.Publish(eventbus.NewSessionEvent(
		eventbus.EventPlayerLeft,
		sessionID,
		playerID,
		map[string]interface{}{
			"player_count": session.PlayerCount(),
		},
	))

	log.Infof("Player %s left session %s", playerID, sessionID)
	return nil
}

// saveSession 保存会话到存储（已禁用）
/*
func (m *SessionManager) saveSession(session GameSession) error {
	serializable, ok := session.(SerializableSession)
	if !ok {
		return errors.New("session does not support serialization")
	}

	data, err := serializable.Serialize()
	if err != nil {
		return err
	}

	// 设置会话过期时间（超时时间 + 缓冲）
	expiration := m.config.SessionTimeout + 5*time.Minute
	return m.storage.SaveSession(session.ID(), data, expiration)
}*/

// loadSession 从存储加载会话（已禁用）
/*
func (m *SessionManager) loadSession(sessionID string) (GameSession, error) {
	data, err := m.storage.LoadSession(sessionID)
	if err != nil {
		return nil, err
	}

	// 创建新的BaseSession并反序列化数据
	session := &BaseSession{}
	if err := session.Deserialize(data); err != nil {
		return nil, err
	}

	return session, nil
}*/

// randomString 生成指定长度的随机字符串（简化实现，实际应使用更安全的随机数生成方式）
// 参数：
//
//	length: 随机字符串的长度（当前代码传入0，返回空字符串）
//
// 返回值：
//
//	string: 生成的随机字符串（由大小写字母和数字组成）
func randomString(length int) string {
	const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" // 随机字符集
	result := make([]byte, length)                                                   // 初始化字节切片，用于存储随机字符

	// 遍历切片，为每个位置生成随机字符（基于当前时间的纳秒数取模，简化实现，安全性较低）
	for i := range result {
		// time.Now().UnixNano()：获取当前时间的纳秒数（作为随机种子）
		// 对字符集长度取模，确保索引在合法范围内
		result[i] = charset[time.Now().UnixNano()%int64(len(charset))]
	}
	return string(result)
}

// RestoreSessions 服务器启动时恢复所有存储的会话（已禁用）
/*
func (m *SessionManager) RestoreSessions() error {
	m.mu.Lock()
	defer m.mu.Unlock()

	// 获取所有会话键（需要Redis支持Keys命令或使用SCAN）
	// 这里简化实现，实际应根据存储特性实现
	// 假设我们存储了会话ID列表在特定键中
	sessionListKey := "game_sessions:active"

	// 从Redis获取会话ID列表
	sessionIDsData, err := m.storage.LoadSession(sessionListKey)
	if err != nil {
		// 可能没有会话列表，不是错误
		return nil
	}

	var sessionIDs []string
	if err := json.Unmarshal(sessionIDsData, &sessionIDs); err != nil {
		return err
	}

	// 恢复每个会话
	restoredCount := 0
	for _, sessionID := range sessionIDs {
		if err := m.restoreSingleSession(sessionID); err != nil {
			log.Infof("Failed to restore session %s: %v", sessionID, err)
			continue
		}
		restoredCount++
	}

	log.Infof("Successfully restored %d sessions from storage", restoredCount)
	return nil
}*/
// restoreSingleSession 恢复单个会话（已禁用）
/*
func (m *SessionManager) restoreSingleSession(sessionID string) error {
	// 检查会话是否已存在（避免重复恢复）
	if _, exists := m.sessions[sessionID]; exists {
		return nil
	}

	// 从存储加载会话数据
	data, err := m.storage.LoadSession(sessionID)
	if err != nil {
		return err
	}

	// 创建会话并反序列化
	session := &BaseSession{}
	if err := session.Deserialize(data); err != nil {
		return err
	}

	// 添加到管理器
	m.sessions[sessionID] = session

	// 发布会话恢复事件
	m.eventBus.Publish(eventbus.NewSessionEvent(
		eventbus.EventSessionRestored,
		sessionID,
		"",
		map[string]interface{}{
			"player_count": session.PlayerCount(),
		},
	))

	return nil
}*/
// 修改会话状态变更方法，添加持久化（已禁用）
/*
func (m *SessionManager) updateSessionState(sessionID string, newState SessionState) error {
	session, exists := m.sessions[sessionID]
	if !exists {
		return errors.New("session not found")
	}

	// 这里需要BaseSession有SetState方法，或者通过其他方式修改状态
	// 假设BaseSession有SetState方法
	if baseSession, ok := session.(*BaseSession); ok {
		baseSession.SetState(newState)

		// 保存状态变更
		if err := m.saveSession(session); err != nil {
			return err
		}
	}

	return nil
}*/

// 会话列表存储键
// const sessionListKey = "game_sessions:active_list"

// saveSessionList 保存活跃会话ID列表到存储（已禁用）
/*
func (m *SessionManager) saveSessionList() error {
	m.mu.RLock()
	defer m.mu.RUnlock()

	// 收集所有活跃会话ID
	sessionIDs := make([]string, 0, len(m.sessions))
	for sessionID := range m.sessions {
		sessionIDs = append(sessionIDs, sessionID)
	}

	// 序列化会话列表
	data, err := json.Marshal(sessionIDs)
	if err != nil {
		return err
	}

	// 保存到存储（设置较长的过期时间）
	return m.storage.SaveSession(sessionListKey, data, 24*time.Hour)
}*/

// addSessionToList 添加会话到列表（已禁用）
/*
func (m *SessionManager) addSessionToList(sessionID string) error {
	// 先获取现有列表
	existingData, err := m.storage.LoadSession(sessionListKey)
	var sessionIDs []string

	if err == nil {
		// 成功加载现有列表
		json.Unmarshal(existingData, &sessionIDs)
	} else {
		// 创建新列表
		sessionIDs = make([]string, 0)
	}

	// 检查是否已存在
	for _, id := range sessionIDs {
		if id == sessionID {
			return nil // 已存在，无需添加
		}
	}

	// 添加新会话ID
	sessionIDs = append(sessionIDs, sessionID)

	// 保存更新后的列表
	data, err := json.Marshal(sessionIDs)
	if err != nil {
		return err
	}

	return m.storage.SaveSession(sessionListKey, data, 24*time.Hour)
}*/

// removeSessionFromList 从列表中移除会话（已禁用）
/*
func (m *SessionManager) removeSessionFromList(sessionID string) error {
	// 获取现有列表
	existingData, err := m.storage.LoadSession(sessionListKey)
	if err != nil {
		return err // 列表不存在，无需移除
	}

	var sessionIDs []string
	if err := json.Unmarshal(existingData, &sessionIDs); err != nil {
		return err
	}

	// 查找并移除会话ID
	for i, id := range sessionIDs {
		if id == sessionID {
			sessionIDs = append(sessionIDs[:i], sessionIDs[i+1:]...)
			break
		}
	}

	// 保存更新后的列表
	data, err := json.Marshal(sessionIDs)
	if err != nil {
		return err
	}

	return m.storage.SaveSession(sessionListKey, data, 24*time.Hour)
}*/

// SessionStats 会话统计信息
type SessionStats struct {
	TotalSessions    int           `json:"total_sessions"`
	ActiveSessions   int           `json:"active_sessions"`
	IdleSessions     int           `json:"idle_sessions"`
	MatchingSessions int           `json:"matching_sessions"`
	ReadySessions    int           `json:"ready_sessions"`
	PlayingSessions  int           `json:"playing_sessions"`
	PausedSessions   int           `json:"paused_sessions"`
	FinishedSessions int           `json:"finished_sessions"`
	TotalPlayers     int           `json:"total_players"`
	AveragePlayers   float64       `json:"average_players"`
	MaxPlayers       int           `json:"max_players"`
	Uptime           time.Duration `json:"uptime"`
	CreatedAt        time.Time     `json:"created_at"`
}

// Monitor 会话监控器
type Monitor struct {
	manager   *SessionManager
	stats     SessionStats
	mu        sync.RWMutex
	startTime time.Time
	stopChan  chan struct{}
}

// NewMonitor 创建会话监控器
func NewMonitor(manager *SessionManager) *Monitor {
	return &Monitor{
		manager:   manager,
		startTime: time.Now(),
		stopChan:  make(chan struct{}),
	}
}

// Start 启动监控
func (m *Monitor) Start(interval time.Duration) {
	ticker := time.NewTicker(interval)

	go func() {
		for {
			select {
			case <-ticker.C:
				m.collectStats()
			case <-m.stopChan:
				ticker.Stop()
				return
			}
		}
	}()
}

// Stop 停止监控
func (m *Monitor) Stop() {
	close(m.stopChan)
}

// collectStats 收集统计信息
func (m *Monitor) collectStats() {
	m.manager.mu.RLock()
	defer m.manager.mu.RUnlock()

	stats := SessionStats{
		TotalSessions: len(m.manager.sessions),
		Uptime:        time.Since(m.startTime),
		CreatedAt:     m.startTime,
	}

	totalPlayers := 0
	maxPlayers := 0

	for _, session := range m.manager.sessions {
		playerCount := session.PlayerCount()
		totalPlayers += playerCount

		if playerCount > maxPlayers {
			maxPlayers = playerCount
		}

		switch session.State() {
		case StateIdle:
			stats.IdleSessions++
		case StateMatching:
			stats.MatchingSessions++
		case StateReady:
			stats.ReadySessions++
		case StatePlaying:
			stats.PlayingSessions++
		case StatePaused:
			stats.PausedSessions++
		case StateFinished:
			stats.FinishedSessions++
		}
	}

	stats.ActiveSessions = stats.TotalSessions - stats.FinishedSessions
	stats.TotalPlayers = totalPlayers
	stats.MaxPlayers = maxPlayers

	if stats.TotalSessions > 0 {
		stats.AveragePlayers = float64(totalPlayers) / float64(stats.TotalSessions)
	}

	m.mu.Lock()
	m.stats = stats
	m.mu.Unlock()

	// 发布统计事件
	m.manager.eventBus.Publish(eventbus.NewBaseEvent(
		eventbus.EventSessionStatsUpdated,
		map[string]interface{}{
			"stats": stats,
		},
	))
}

// GetStats 获取当前统计信息
func (m *Monitor) GetStats() SessionStats {
	m.mu.RLock()
	defer m.mu.RUnlock()
	return m.stats
}
